package io.renren.modules.medical.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.exception.MedicalException;
import io.renren.common.result.ResultCodeEnum;
import io.renren.common.utils.*;
import io.renren.modules.medical.dao.MedicationAdviceDao;
import io.renren.modules.medical.entity.*;
import io.renren.modules.medical.service.DoctorInfoService;
import io.renren.modules.medical.service.IllSubService;
import io.renren.modules.medical.service.MedicationAdviceService;
import io.renren.modules.medical.service.PatientInfoService;
import io.renren.modules.medical.vo.medicalVo.MedicationAdviceListVo;
import io.renren.modules.medical.vo.medicalVo.StatusVo;
import io.renren.modules.medical.vo.weixinVo.ApiAdviceListVo;
import io.renren.modules.sys.service.SysUserRoleService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.metadata.IPage;

@RequiredArgsConstructor
@Service("medicationAdviceService")
public class MedicationAdviceServiceImpl extends ServiceImpl<MedicationAdviceDao, MedicationAdviceEntity> implements MedicationAdviceService {

    private final PatientInfoService patientInfoService;

    private final IllSubService illSubService;

    private final DoctorInfoService doctorInfoService;

    private final SysUserRoleService sysUserRoleService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        LambdaQueryWrapper<MedicationAdviceEntity> queryWrapper = new LambdaQueryWrapper<>();
        // 设置基础构造条件
        String key = (String)params.get("key");
        // 根据原有参数获取原有的HealthGuidanceEntity集合
        if (StringUtils.isNotEmpty(key) && StringUtils.isNumeric(key)){
            // 通过patientId来查找
            Long patientId = Long.valueOf(key);
            queryWrapper.eq(MedicationAdviceEntity::getPatientId, patientId);

        }else if (StringUtils.isNotEmpty(key)){
            // 通过病人姓名来查找
            List<Long> patientIds = patientInfoService.getIdsByName(key);
            if (patientIds == null || patientIds.size() <= 0){
                throw new MedicalException(ResultCodeEnum.NOT_FIND_ERROR.getCode(), "没有对应姓名的病人");
            }
            queryWrapper.in(MedicationAdviceEntity::getPatientId, patientIds);

        }

        // 判断当前用户是医生还是管理员或者审核
        List<Long> roles = DoctorInfoUtils.getRole(sysUserRoleService);

        if (roles.contains(Constant.SysRole.ADMIN.getValue()) || roles.contains(Constant.SysRole.AUDITOR.getValue()) ){
            // 访问全部
        }else if( roles.contains(Constant.SysRole.DOCTOR.getValue()) ){
            // 医生就只访问当前医生创建的
            DoctorInfoEntity doctorInfo = DoctorInfoUtils.getDoctorInfo(doctorInfoService);
            queryWrapper.eq(QueryPageBaseEntity::getDoctorId, doctorInfo.getId());
        }else{
            throw new MedicalException(HttpStatus.SC_FORBIDDEN, "用户无权访问健康指导列表");
        }

        // 根据修改时间排序
        queryWrapper.orderByDesc(BaseEntity::getUpdateTime);
        // 获取基础实体集合
        IPage<MedicationAdviceEntity> page = this.page(
                new Query<MedicationAdviceEntity>().getPage(params),
                queryWrapper
        );

        // 封装集合作为页面返回值
        List<MedicationAdviceEntity> records = page.getRecords();
        List<MedicationAdviceListVo> medicationAdviceListVos = records.stream().map(
            // 调用方法将需要的属性封装进来
            item -> (MedicationAdviceListVo) QueryPageUtils.listToVos(new MedicationAdviceListVo(), item, patientInfoService, illSubService, doctorInfoService)
        ).collect(Collectors.toList());

        Page<MedicationAdviceListVo> medicationAdviceVoPage = new Page<>();
        BeanUtils.copyProperties(page, medicationAdviceVoPage);
        medicationAdviceVoPage.setRecords(medicationAdviceListVos);
        return new PageUtils(medicationAdviceVoPage);
    }

    @Override
    public void updateStatus(StatusVo statusVo) {
        MedicationAdviceEntity medicationAdviceEntity = new MedicationAdviceEntity();
        BeanUtils.copyProperties(statusVo, medicationAdviceEntity);
        this.updateById(medicationAdviceEntity);
    }

    /**
     * 获取返回小程序端的用药建议list
     * @return
     */
    @Override
    public List<ApiAdviceListVo> getAdviceList() {
        // TODO 通过filter获取到到patientId
        Long patientId = 1L;
        // 根据病人Id获取到用药建议
        LambdaQueryWrapper<MedicationAdviceEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(QueryPageBaseEntity::getPatientId, patientId);
        // 只查询在使用中的用药建议
        queryWrapper.eq(MedicationAdviceEntity::getStatus, 1);
        List<MedicationAdviceEntity> entityList = this.list(queryWrapper);

        if (entityList == null || entityList.size() <= 0){
            throw new MedicalException(ResultCodeEnum.NOT_FIND_ERROR.getCode(), "用药建议暂时为空");
        }

        // 遍历封装
        List<ApiAdviceListVo> adviceListVos = entityList.stream().map(item -> {
            ApiAdviceListVo apiAdviceListVo = new ApiAdviceListVo();
            BeanUtils.copyProperties(item, apiAdviceListVo);
            Long doctorId = item.getDoctorId();
            DoctorInfoEntity doctorInfoEntity = doctorInfoService.getById(doctorId);
            apiAdviceListVo.setDoctorName(doctorInfoEntity.getName());
            IllSubEntity illSubEntity = illSubService.getById(item.getSubId());
            apiAdviceListVo.setSubTitle(illSubEntity == null ? "暂无" : illSubEntity.getTitle());
            return apiAdviceListVo;
        }).collect(Collectors.toList());

        return adviceListVos;
    }

    // 保存用药建议
    @Override
    public void saveMedicationAdvice(MedicationAdviceEntity medicationAdvice) {
        DoctorInfoEntity doctorInfo = DoctorInfoUtils.getDoctorInfo(doctorInfoService);
        medicationAdvice.setDoctorId(doctorInfo.getId());
        this.save(medicationAdvice);
    }

}